/*
 *  您可以更改此项目但请不要删除作者署名谢谢，否则根据中华人民共和国版权法进行处理.
 *  You may change this item but please do not remove the author's signature,
 *  otherwise it will be dealt with according to the Copyright Law of the People's Republic of China.
 *
 *  如果需要联系到我请加Wechat: yangbuyiya 备注交流学习
 *  If you need to contact me, please add Wechat: yangbuyiya as a note to exchange and learn.
 *  yangbuyi Copyright (c) https://yby6.com 2024.
 */

package com.yby6.service;

import cn.hutool.json.JSONUtil;
import com.tencent.asr.model.FlashRecognitionResponse;
import com.yby6.config.properties.YuanQiSDKConfigProperties;
import com.yby6.constants.AppConstants;
import com.yby6.enums.AgentEnum;
import com.yby6.req.vo.ChatYuanQiRequestVo;
import com.yby6.resp.dto.ChatYuanQiRequestDto;
import com.yby6.utils.AsrUtils;
import com.yby6.utils.TtsUtils;
import com.yby6.utils.file.FileUtil;
import com.yby6.yuanqi.sdk.common.Constants;
import com.yby6.yuanqi.sdk.domain.yuanqi.Message;
import com.yby6.yuanqi.sdk.domain.yuanqi.MessageContent;
import com.yby6.yuanqi.sdk.domain.yuanqi.YuanQiCompletionRequest;
import com.yby6.yuanqi.sdk.session.ApiKeyProvider;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.handle.DownloadedFile;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 音频服务 & 问答
 *
 * @author Yang Shuai
 * Create By 2024/6/20
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class AudioService {

    @Inject
    private YuanQiService yuanQiService;
    @Inject
    private YuanQiSDKConfigProperties yuanQiSDKConfigProperties;

    /**
     * 元器智能体问答
     * <p>
     * 支持传递音频Base64文件
     * 支持传递普通文本
     * </p>
     *
     * @param chatYuanQiRequestVo 问答聚合
     */
    public ChatYuanQiRequestDto chatCompletion(ChatYuanQiRequestVo chatYuanQiRequestVo) {

        // 1. 根据前端传递的数据来判断不同的业务 前端会传递base64的录音文件来识别 或者 经过实时语音识别的文本
        String message = chatYuanQiRequestVo.getAudioFile();

        List<Message> messageList = chatYuanQiRequestVo.getMessages();

        // 判断是否包含音频文件
        if (chatYuanQiRequestVo.getAudioFile().contains(AppConstants.BASE64_AUDIO)) {
            DownloadedFile downloadedFile = FileUtil.base64ToDownloadedFile(message);
            // 1.先语音识别出文本
            FlashRecognitionResponse voicedToTextSpeedEdition = AsrUtils.voiceToTextSpeedEdition(downloadedFile);
            message = voicedToTextSpeedEdition.getFlashResult().get(0).getText();
            // messageList 最后一个text更改为message
            if (!messageList.isEmpty()) {
                messageList.get(messageList.size() - 1).getContent().get(0).setText(message);
            } else {
                List<Message> messages = new ArrayList<>();
                messages.add(Message.builder().role(Constants.Role.USER).
                        content(Collections.singletonList(MessageContent.builder()
                                .text(message)
                                .type(Constants.Type.TEXT).build())).build());
                messageList = messages;
            }
            log.info("录音文件识别完毕: {}", message);
        }

        // 2.元器智能体问答 详细教程前往 继ChatGPT的热潮AI的新产物-智能体元器Agent平台 https://cloud.tencent.com/developer/article/2423792

        // 2.1 设置智能体数据
        AgentEnum agent = AgentEnum.getAgent(chatYuanQiRequestVo.getAssistantId());
        log.info("当前使用智能体:{}", agent.getName());
        // 2.2 构建请求体
        YuanQiCompletionRequest request = yuanQiSDKConfigProperties.builder()
                .stream(false)
                .userId(agent.getUserId())
                .assistantId(agent.getAssistantId())
                .messages(messageList).build();
        // 2.3 设置智能体Token
        ApiKeyProvider.setApiKey(agent.getToken());

        log.info("request: {}", JSONUtil.toJsonStr(request));
        String completions = yuanQiService.completions(request);
        log.info("completions: {}", completions);

        // 3.语音合成
        String voice = TtsUtils.textToVoice(completions);
        log.info("合成结束");
        return ChatYuanQiRequestDto.builder()
                .userMessage(message)
                .botMessage(completions)
                .botVoice(voice).build();
    }
}
